<template>
  <div>
    <el-tree
      ref="tagTreeRef"
      key="tag"
      :data="noteData"
      :props="defaultProps"
      @node-click="handleNodeClick"
      :default-expand-all="isExpandAll"
      :expand-on-click-node="false"
      node-key="id"
      @node-contextmenu="handleContextmenu"
      @node-expand="openTreeNode"
      @node-collapse="closeTreeNode"
      highlight-current
    >
      <template #default="{ node, data }">
        <div class="custom-tree-node">
          <div
            style="display: flex; align-items: center; gap: 2px; width: 100%"
          >
            <el-icon v-if="data.icon" size="16" style="color: var(--tag-color)">
              <Component :is="data.icon"></Component>
            </el-icon>
            <!-- {{ node.label }} -->
            <!-- <el-text
              class="mb-2"
              style="padding-right: 10px; width: 120px"
              truncated
            >
              {{ node.label }}
            </el-text> -->
            <el-text style="padding-right: 10px; width: 80%" truncated>
              {{ node.label }}
            </el-text>
          </div>
          <div v-if="node.level === 1">
            <el-icon @click="handleAddTag(data)"><Plus /></el-icon>
          </div>
        </div>
      </template>
    </el-tree>
    <el-dialog
      v-model="dialogVisible"
      draggable
      overflow
      :title="`${isEdit ? '重命名' : '新建'}标签`"
      width="500"
      destroy-on-close
      @close="resetForm(ruleFormRef)"
    >
      <el-form
        ref="ruleFormRef"
        style="max-width: 600px"
        :model="fileForm"
        label-width="auto"
        size="default"
        :rules="rules"
      >
        <el-form-item label="标签名称" prop="name">
          <el-input v-model="fileForm.name" placeholder="请输入标签名称" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="resetForm(ruleFormRef)">取消</el-button>
          <el-button
            type="primary"
            :loading="modifyFileLoading"
            @click="submitForm(ruleFormRef)"
          >
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
    <div v-show="showTreeMenu" class="treeMenus">
      <div class="btns-wrapper" style="display: flex; flex-direction: column">
        <el-button
          v-for="(button, n) in moreFilledButtons"
          :key="n"
          style="
            margin: 0 !important;
            border: none !important;
            justify-content: flex-start;
          "
          @click="handleMoreFilledClick(button)"
        >
          {{ button.label }}
        </el-button>
      </div>
    </div>

    <el-dialog
      v-model="deleteFile"
      width="400"
      :show-close="false"
      destroy-on-close
      top="30vh"
    >
      <template #header="{ titleId, titleClass }">
        <div class="my-header">
          <h3
            :id="titleId"
            :class="titleClass"
            style="display: flex; align-items: center; gap: 4px"
          >
            <el-icon color="#f5922f"><WarningFilled /></el-icon> 确认删除？
          </h3>
          <p style="color: #7c8599; margin-top: 8px">
            删除内容将进入回收站，30天后自动彻底删除。
          </p>
        </div>
      </template>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="deleteFile = false">取消</el-button>
          <el-button type="primary" @click="deleteNoteConfirm">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, watch, reactive, nextTick, inject } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router'
import {
  httpCreateTag,
  httpDeleteTag,
  httpgetTagList,
  httpUpdateTag,
  httpAddShortCut,
} from '@/api/note'
import useNoteStore from '@/stores/note'
import { storeToRefs } from 'pinia'
import { Plus, WarningFilled } from '@element-plus/icons-vue'
const router = useRouter()
const noteState = useNoteStore()
const { selectedFolder, shortCutData } = storeToRefs(noteState)
const tagTreeRef = ref()
const moreFilledButtons = ref([
  {
    id: '1',
    label: '重命名',
  },
  {
    id: '2',
    label: '删除',
  },
  {
    id: '3',
    label: '添加到快捷方式',
  },
  {
    id: '4',
    label: '取消添加到所有笔记',
  },
])

const isExpandAll = ref(true)
const ruleFormRef = ref()
const validateFileName = (rule, value, callback) => {
  let flag = noteData.value[0].children.some((x) => {
    return x.label === value
  })
  if (value === '') {
    callback(new Error('请输入标签名称'))
  } else if (flag) {
    callback(new Error('标签名称重复'))
  } else {
    callback()
  }
}
const rules = {
  name: [
    {
      required: true,
      message: '请输入笔记文件名称',
      trigger: ['blur', 'change'],
    },
    {
      validator: validateFileName,
    },
  ],
}
const fileForm = reactive({
  name: '',
})
const noteData = ref([
  {
    id: 0,
    label: '标签',
    icon: 'CollectionTag',
    children: [],
  },
])
const modifyFileLoading = ref(false)
const dialogVisible = ref(false)
const showTreeMenu = ref(false)
const isEdit = ref(false)
const deleteFile = ref(false)
const selectedNote = ref()
const model = defineModel()
const appendParentData = ref()
const getAllTagList = async () => {
  const res = await httpgetTagList()
  if (res && res.list.length) {
    noteData.value[0].children = res.list
    noteState.setTagList(res.list)
  }
}
getAllTagList()
const handleAddTag = () => {
  isEdit.value = false
  closeShortCut()
  dialogVisible.value = true
  showTreeMenu.value = false
}
const submitForm = async (formEl) => {
  if (!formEl) return
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      if (isEdit.value) {
        const res = await httpUpdateTag({
          label_id: appendParentData.value.id,
          label: fileForm.name,
        })
        if (res) {
          getAllTagList()
          ElMessage({
            message: '修改成功',
            type: 'success',
          })
        } else {
          ElMessage({
            message: '修改失败',
            type: 'error',
          })
        }
      } else {
        // TODO: 调用新增接口
        const res = await httpCreateTag({
          label: fileForm.name,
        })
        if (res) {
          getAllTagList()
          ElMessage({
            message: '添加成功',
            type: 'success',
          })
        }
      }
      dialogVisible.value = false
      formEl.resetFields()
    } else {
      console.log('error submit!', fields)
    }
  })
}
const deleteNoteConfirm = async () => {
  const res = await httpDeleteTag({
    label_id: appendParentData.value.id,
  })
  if (res) {
    ElMessage.success('删除成功')
    getAllTagList()
    router.push('/file/note/1')
  } else {
    ElMessage.error('删除失败')
  }
  deleteFile.value = false
}
const resetForm = (formEl) => {
  if (!formEl) return
  dialogVisible.value = false
  formEl.resetFields()
  fileForm.name = ''
}
const handleMoreFilledClick = async (button) => {
  if (button.id === '1') {
    // 1.重命名
    fileForm.name = appendParentData.value.label
    dialogVisible.value = true
    isEdit.value = true
  } else if (button.id === '2') {
    // 2. 删除
    deleteFile.value = true
  } else if (button.id === '3') {
    // 3.添加到快捷方式
    showTreeMenu.value = false
    let flag = shortCutData.value && shortCutData.value[0].children
    if (flag.length && flag.some((x) => x.id === appendParentData.value.id)) {
      return ElMessage.error('快捷方式已存在')
    }
    const res = await httpAddShortCut({
      shortcut_id: appendParentData.value.id,
      shortcut_type: 3,
    })
    if (res) {
      ElMessage.success('添加成功')
      await noteState.getShortCutList()
    }
  } else if (button.id === '4') {
    // 4.取消标签关联
    ElMessageBox.confirm(
      `确定要取消标签${appendParentData.value.label}所有关联吗？`,
      `标签${appendParentData.value.label}`,
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      },
    )
      .then(() => {
        ElMessage({
          type: 'success',
          message: '删除成功',
        })
      })
      .catch(() => {})
  }
}

const handleNodeClick = (data, a) => {
  closeShortCut()
  emit('hide')
  emit('clearHighLight')
  if (a.level === 1) {
    return
  }
  selectedNote.value = data
  model.value = data
  showTreeMenu.value = false
  selectedFolder.value = ''
  router.push('/file/note')
}
function handleContextmenu(event, data, node, target) {
  emit('hide')
  closeShortCut()
  if (node.level === 1) {
    showTreeMenu.value = false
  } else {
    appendParentData.value = data
    event.preventDefault()
    showTreeMenu.value = true // 显示菜单
    const mouseY = event.clientY // 获取鼠标右击事件的垂直坐标
    const viewportHeight = window.innerHeight // 获取视口的高度
    const distanceToBottom = viewportHeight - mouseY // 计算距离视口底部的距离
    if (distanceToBottom < 150) {
      document
        .querySelector('.treeMenus')
        .setAttribute(
          'style',
          `top:${event.clientY - 100}px;left:${event.clientX + 10}px;`,
        )
    } else {
      document
        .querySelector('.treeMenus')
        .setAttribute(
          'style',
          `top:${event.clientY}px;left:${event.clientX + 10}px;`,
        )
    }

    document.addEventListener('click', closePopOver)
    document.addEventListener('contextmenu', closePopOver)
  }
}
const openTreeNode = () => {
  showTreeMenu.value = false
  closeShortCut()
  emit('hide')
}
const closeTreeNode = () => {
  showTreeMenu.value = false
  closeShortCut()
  emit('hide')
}
function closePopOver() {
  showTreeMenu.value = false
}
const emit = defineEmits(['hide', 'clearHighLight'])
function setTagTreeRefKey() {
  tagTreeRef.value.setCurrentKey()
}
defineExpose({
  close: closePopOver,
  setTagTreeRefKey,
})

const defaultProps = {
  children: 'children',
  label: 'label',
}
const parentTreeWrapper = inject('operationDom') // 注入
const closeShortCut = inject('closeShortCut')
watch(
  () => showTreeMenu.value,
  () => {
    if (showTreeMenu.value) {
      nextTick(() => {
        parentTreeWrapper.value.style.overflow = 'hidden'
      })
    } else {
      nextTick(() => {
        parentTreeWrapper.value.style.overflow = 'auto'
      })
    }
  },
)
</script>
<style scoped lang="scss">
.custom-tree-node {
  width: 100%;
  display: flex;
  gap: 14px;
  align-items: center;
  // justify-content: space-between;
}
.treeMenus {
  font-size: 14px;
  position: fixed;
  padding: 2px 0 5px;
  z-index: 999;
  top: 50%;
  left: 50%;
  background-color: #fff;
  overflow: hidden;
  border-radius: 5px;
  border: 1px solid #e6ebf5;
  div:hover {
    cursor: pointer;
  }
}
</style>
